package com.sky.chapter3.add;

import java.util.concurrent.CountDownLatch;

/**
 * JUC强大的辅助类
 * 它主要用来协调多个线程之间的同步，起到一个同步器的作用。
 * 总的来说，CountDownLatch让一个或多个线程在运行过程中的某个时间点能停下来等待其他的一些线程完成某些任务后再继续运行。
 * CountDownLatch主要有两个方法，当一个或多个线程调用await方法时，这些线程会阻塞。
 * 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞)，
 * 当计数器的值变为0时，因await方法阻塞的线程会被唤醒，继续执行
 *
 * 类似的任务可以使用线程的 join() 方法实现：在等待时间点调用其他线程的 join() 方法，
 * 当前线程就会等待join线程执行完之后才继续执行，但 CountDownLatch 实现更加简单，并且比 join 的功能更多。
 *
 *
 * 它是使用了一个内部同步器AQS来实现屏蔽功能的。只有当count的值为零时，同步器的tryAcquireShared的结果为1，其他时候都是-1。
 *
 *
 */
public class CountDownLatchDemo {

    //线程顺序执行
    private static void withCountDownLatch() throws InterruptedException {
        // 总数是6，必须要执行任务的时候，再使用！
        CountDownLatch countDownLatch = new CountDownLatch(6);
        //6 个线程去跑
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " Go out");
                countDownLatch.countDown(); // 数量-1
                System.out.println("线程最后执行部分");
            }, String.valueOf(i)).start();
        }

        countDownLatch.await(); // 卡住, 等待计数器归零，然后再向下执行

        System.out.println("Close Door");

    }


    //没有顺序
    private static void withNoCountDownLatch() {

        for (int i = 1; i <= 6; i++) {
            new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(Thread.currentThread().getName() + " Go out");

                        }
                    }, String.valueOf(i)).start();
        }
        System.out.println("Close Door");

    }


    public static void main(String[] args) throws InterruptedException {
//        withNoCountDownLatch();
         withCountDownLatch();

    }
}
